package org.dxy.trigger.http.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dxy.api.dto.param.CreateProcessParamRequest;
import org.dxy.api.dto.param.UpdateProcessParamRequest;
import org.dxy.api.response.R;
import org.dxy.infrastructure.persistent.db.mybatispuls.po.ProcessParamRequirementPo;
import org.dxy.infrastructure.persistent.db.mybatispuls.service.ProcessParamRequirementService;
import org.dxy.trigger.http.service.ProcessParamApplicationService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * @description: 工序参数配置应用服务实现类
 * @author: dxy
 * @createTime: 2025/1/21
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class ProcessParamApplicationServiceImpl implements ProcessParamApplicationService {

    private final ProcessParamRequirementService processParamRequirementService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R<Long> create(CreateProcessParamRequest dto) {
        log.info("创建工序参数配置 - 工序ID: {}, 参数定义ID: {}", dto.getProcessId(), dto.getParamDefinitionId());

        // 检查工序参数配置是否已存在
        int count = processParamRequirementService.checkProcessParamExists(dto.getProcessId(), dto.getParamDefinitionId(), null);
        if (count > 0) {
            log.warn("工序参数配置已存在 - 工序ID: {}, 参数定义ID: {}", dto.getProcessId(), dto.getParamDefinitionId());
            return R.fail("该工序已配置此参数");
        }

        // 创建工序参数配置实体
        ProcessParamRequirementPo entity = new ProcessParamRequirementPo();
        BeanUtils.copyProperties(dto, entity);

        // 保存到数据库
        boolean result = processParamRequirementService.save(entity);
        if (result) {
            log.info("工序参数配置创建成功 - ID: {}, 工序ID: {}, 参数定义ID: {}", 
                    entity.getId(), dto.getProcessId(), dto.getParamDefinitionId());
            return R.ok(entity.getId());
        } else {
            log.error("工序参数配置创建失败 - 工序ID: {}, 参数定义ID: {}", dto.getProcessId(), dto.getParamDefinitionId());
            return R.fail("工序参数配置创建失败");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R<Void> update(UpdateProcessParamRequest dto) {
        log.info("更新工序参数配置 - ID: {}", dto.getId());

        // 检查工序参数配置是否存在
        ProcessParamRequirementPo existEntity = processParamRequirementService.getById(dto.getId());
        if (existEntity == null) {
            log.warn("工序参数配置不存在 - ID: {}", dto.getId());
            return R.fail("工序参数配置不存在");
        }

        // 检查工序参数配置是否已被其他记录使用
        int count = processParamRequirementService.checkProcessParamExists(dto.getProcessId(), dto.getParamDefinitionId(), dto.getId());
        if (count > 0) {
            log.warn("工序参数配置已被其他记录使用 - 工序ID: {}, 参数定义ID: {}", dto.getProcessId(), dto.getParamDefinitionId());
            return R.fail("该工序已配置此参数");
        }

        // 更新工序参数配置实体
        ProcessParamRequirementPo entity = new ProcessParamRequirementPo();
        BeanUtils.copyProperties(dto, entity);

        // 更新到数据库
        boolean result = processParamRequirementService.updateById(entity);
        if (result) {
            log.info("工序参数配置更新成功 - ID: {}", dto.getId());
            return R.ok();
        } else {
            log.error("工序参数配置更新失败 - ID: {}", dto.getId());
            return R.fail("工序参数配置更新失败");
        }
    }

    @Override
    public R<Page<ProcessParamRequirementPo>> list(Page<ProcessParamRequirementPo> page, ProcessParamRequirementPo query) {
        log.info("分页查询工序参数配置列表 - 页码: {}, 每页大小: {}", page.getCurrent(), page.getSize());

        try {
            Page<ProcessParamRequirementPo> result = processParamRequirementService.selectPageListWithDetails(page, query);
            log.info("工序参数配置列表查询成功 - 总数: {}", result.getTotal());
            return R.ok(result);
        } catch (Exception e) {
            log.error("工序参数配置列表查询失败", e);
            return R.fail("工序参数配置列表查询失败: " + e.getMessage());
        }
    }

    @Override
    public R<ProcessParamRequirementPo> getById(Long id) {
        log.info("查询工序参数配置详情 - ID: {}", id);

        try {
            ProcessParamRequirementPo entity = processParamRequirementService.selectByIdWithDetails(id);
            if (entity != null) {
                log.info("工序参数配置详情查询成功 - ID: {}", id);
                return R.ok(entity);
            } else {
                log.warn("工序参数配置不存在 - ID: {}", id);
                return R.fail("工序参数配置不存在");
            }
        } catch (Exception e) {
            log.error("工序参数配置详情查询失败 - ID: {}", id, e);
            return R.fail("工序参数配置详情查询失败: " + e.getMessage());
        }
    }

    @Override
    public R<List<ProcessParamRequirementPo>> getByProcessId(Long processId) {
        log.info("根据工序ID查询参数配置列表 - 工序ID: {}", processId);

        try {
            List<ProcessParamRequirementPo> list = processParamRequirementService.selectByProcessIdWithDetails(processId);
            log.info("根据工序ID查询参数配置列表成功 - 工序ID: {}, 数量: {}", processId, list.size());
            return R.ok(list);
        } catch (Exception e) {
            log.error("根据工序ID查询参数配置列表失败 - 工序ID: {}", processId, e);
            return R.fail("根据工序ID查询参数配置列表失败: " + e.getMessage());
        }
    }

    @Override
    public R<List<ProcessParamRequirementPo>> getByParamDefinitionId(Long paramDefinitionId) {
        log.info("根据参数定义ID查询工序参数配置列表 - 参数定义ID: {}", paramDefinitionId);

        try {
            List<ProcessParamRequirementPo> list = processParamRequirementService.selectByParamDefinitionIdWithDetails(paramDefinitionId);
            log.info("根据参数定义ID查询工序参数配置列表成功 - 参数定义ID: {}, 数量: {}", paramDefinitionId, list.size());
            return R.ok(list);
        } catch (Exception e) {
            log.error("根据参数定义ID查询工序参数配置列表失败 - 参数定义ID: {}", paramDefinitionId, e);
            return R.fail("根据参数定义ID查询工序参数配置列表失败: " + e.getMessage());
        }
    }

    @Override
    public R<List<ProcessParamRequirementPo>> getRequiredParams(Long processId) {
        log.info("查询必填参数配置 - 工序ID: {}", processId);

        try {
            List<ProcessParamRequirementPo> list = processParamRequirementService.selectRequiredParamsWithDetails(processId);
            log.info("查询必填参数配置成功 - 工序ID: {}, 数量: {}", processId, list.size());
            return R.ok(list);
        } catch (Exception e) {
            log.error("查询必填参数配置失败 - 工序ID: {}", processId, e);
            return R.fail("查询必填参数配置失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R<List<Long>> batchCreate(List<CreateProcessParamRequest> dtoList) {
        log.info("批量创建工序参数配置 - 数量: {}", dtoList.size());

        List<Long> createdIds = new ArrayList<>();
        List<ProcessParamRequirementPo> entities = new ArrayList<>();

        // 检查每个配置是否已存在
        for (CreateProcessParamRequest dto : dtoList) {
            int count = processParamRequirementService.checkProcessParamExists(dto.getProcessId(), dto.getParamDefinitionId(), null);
            if (count > 0) {
                log.warn("工序参数配置已存在 - 工序ID: {}, 参数定义ID: {}", dto.getProcessId(), dto.getParamDefinitionId());
                return R.fail("工序ID " + dto.getProcessId() + " 已配置参数定义ID " + dto.getParamDefinitionId());
            }

            ProcessParamRequirementPo entity = new ProcessParamRequirementPo();
            BeanUtils.copyProperties(dto, entity);
            entities.add(entity);
        }

        // 批量插入
        int result = processParamRequirementService.batchInsert(entities);
        if (result > 0) {
            // 获取插入后的ID
            for (ProcessParamRequirementPo entity : entities) {
                createdIds.add(entity.getId());
            }
            log.info("批量创建工序参数配置成功 - 创建数量: {}", result);
            return R.ok(createdIds);
        } else {
            log.error("批量创建工序参数配置失败");
            return R.fail("批量创建工序参数配置失败");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R<Void> delete(Long id) {
        log.info("删除工序参数配置 - ID: {}", id);

        // 检查工序参数配置是否存在
        ProcessParamRequirementPo entity = processParamRequirementService.getById(id);
        if (entity == null) {
            log.warn("工序参数配置不存在 - ID: {}", id);
            return R.fail("工序参数配置不存在");
        }

        // 删除工序参数配置
        boolean result = processParamRequirementService.removeById(id);
        if (result) {
            log.info("工序参数配置删除成功 - ID: {}", id);
            return R.ok();
        } else {
            log.error("工序参数配置删除失败 - ID: {}", id);
            return R.fail("工序参数配置删除失败");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R<Void> batchDelete(List<Long> ids) {
        log.info("批量删除工序参数配置 - ID列表: {}", ids);

        // 批量删除工序参数配置
        int result = processParamRequirementService.batchDeleteByIds(ids);
        if (result > 0) {
            log.info("批量删除工序参数配置成功 - 删除数量: {}", result);
            return R.ok();
        } else {
            log.error("批量删除工序参数配置失败 - ID列表: {}", ids);
            return R.fail("批量删除工序参数配置失败");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R<Void> deleteByProcessId(Long processId) {
        log.info("根据工序ID删除所有参数配置 - 工序ID: {}", processId);

        // 根据工序ID删除所有参数配置
        int result = processParamRequirementService.deleteByProcessId(processId);
        log.info("根据工序ID删除所有参数配置成功 - 工序ID: {}, 删除数量: {}", processId, result);
        return R.ok();
    }
}